package com.atdel.demo21;

import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Scanner;

/**
 * @BelongsProject: java_study
 * @BelongsPackage: com.atdel.demo21
 * @Author: Del
 * @CreateTime: 2025-03-17  17:15
 * @Description:
 * 输入一个合法的Email地址，截取其帐户名。
 *     提示：使用字符串对象:substring()、indexOf()方法实现
 *     要求：使用反射实现
 * @Version: 1.0
 */
public class ReflectDemo {
    public static void main(String[] args) {
        try {
            // 通过类名获取Class对象，将java.util.Scanner、java.lang.String和java.lang.System传入
            Class<?> scannerClass = Class.forName("java.util.Scanner");
            Class<?> stringClass = Class.forName("java.lang.String");
            Class<?> systemClass = Class.forName("java.lang.System");

            // 获取Scanner类的指定构造器，参数为InputStream.class，用于创建Scanner实例时传入System.in
            Constructor<?> declaredConstructor = scannerClass.getDeclaredConstructor(InputStream.class);
            Object scannerInstance = declaredConstructor.newInstance(System.in);

            // 获取Scanner类的nextLine方法，用于读取用户输入的一行文本
            Method nextLineMethod = scannerClass.getMethod("nextLine");
            boolean continueLoop = true; // 控制循环的变量，当输入合法时终止循环

            // 使用反射获取System类的out字段（PrintStream对象）
            Field outField = systemClass.getField("out");
            Object printStreamInstance = outField.get(null); // System.out是静态字段，因此传递null

            // 获取PrintStream类的print和flush方法
            Method printMethod = printStreamInstance.getClass().getMethod("print", String.class);
            Method flushMethod = printStreamInstance.getClass().getMethod("flush");

            while (continueLoop) {
                // 使用反射调用System.out.print方法提示用户输入
                printMethod.invoke(printStreamInstance, "请输入Email地址：");
                flushMethod.invoke(printStreamInstance); // 刷新输出流

                // 调用scannerInstance的nextLine方法读取用户输入的字符串
                String email = (String) nextLineMethod.invoke(scannerInstance);

                // 检查输入的字符串是否包含"@"，这是判断Email地址合法性的简单依据
                Method printlnMethod = null;
                if (email.contains("@")) {
                    // 使用反射调用String的indexOf方法找到"@"的位置
                    Method indexOfMethod = stringClass.getMethod("indexOf", String.class);
                    int atIndex = (int) indexOfMethod.invoke(email, "@");

                    // 使用反射调用String的substring方法提取"@"前的部分
                    Method substringMethod = stringClass.getMethod("substring", int.class, int.class);
                    String accountName = (String) substringMethod.invoke(email, 0, atIndex);

                    // 使用反射调用System.out.println方法输出结果
                    printlnMethod = printStreamInstance.getClass().getMethod("println", String.class);
                    printlnMethod.invoke(printStreamInstance, "帐户名：" + accountName);

                    continueLoop = false; // 输入合法，设置continueLoop为false以终止循环
                } else {
                    // 使用反射调用System.out.println方法提示用户重新输入
                    printlnMethod.invoke(printStreamInstance, "输入的Email地址不合法，请重新输入！");
                }
            }
        } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException |
                 InstantiationException | IllegalAccessException | NoSuchFieldException ex) {
            // 捕获反射操作中可能发生的异常，并包装成RuntimeException重新抛出
            throw new RuntimeException(ex);
        }
    }
}
